<template>
  <teleport to="body">
    <div v-show="visible" class="terminal-fullscreen">
      <div class="terminal-controls-floating">
        <button class="terminal-btn" @click="close">关闭</button>
      </div>
      <div class="terminal-fullscreen-container">
        <div ref="termEl" class="terminal-content fullscreen"></div>
      </div>
    </div>
  </teleport>
</template>

<script setup>
import { ref, watch, nextTick, onBeforeUnmount, computed, onMounted, onUnmounted } from 'vue'
import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import 'xterm/css/xterm.css'
import { useTerminalStore } from '@/stores/terminalStore'
import { useRouter } from 'vue-router'

const props = defineProps({
  modelValue: Boolean,
  conn: Object, // {host, port?, username, password}
  fullscreen: { type: Boolean, default: false }
})
const emit = defineEmits(['update:modelValue'])

const visible = ref(false)
const termEl = ref(null)
const terminalStore = useTerminalStore()
const isFullscreen = ref(props.fullscreen)
const router = useRouter()
let term
let unsubscribeOnData = null
let fitAddon = null
let resizeObserver = null
let restoreBodyOverflow = null
let hasAutoStarted = false
let autoStartTimer = null

// 响应式对话框尺寸计算
const dialogWidth = computed(() => {
  if (isFullscreen.value) return '100%'
  const screenWidth = window.innerWidth
  if (screenWidth <= 768) return '95%'
  if (screenWidth <= 1024) return '90%'
  return '80%'
})

const dialogTop = computed(() => {
  if (isFullscreen.value) return '0vh'
  return '5vh'
})

const close = () => {
  // 更新modelValue以关闭对话框
  emit('update:modelValue', false)
  // 取消订阅以避免内存泄漏
  if (unsubscribeOnData) {
    try { unsubscribeOnData(); } catch (_) {}
    unsubscribeOnData = null
  }
  // 延迟导航到主页面，确保关闭动画完成
  setTimeout(() => {
    // 如果当前在终端页面，则导航到仪表板
    if (router.currentRoute.value.path === '/Terminal') {
      router.push('/Dashboard/Analytics')
    }
  }, 300)
}

watch(() => props.modelValue, async val => {
  visible.value = val
  if (val) {
    await nextTick()
    // 如果还没有初始化，则初始化；连接由全局 store 维护
    if (!term) {
      init()
    }
  } else {
    // 不再断开连接，保持终端连接
    // socket?.disconnect()
    // term?.dispose()
  }
  // 根据可见性锁定/恢复页面滚动
  lockBodyScrollIfNeeded()
})

// 同步外部 fullscreen 变更
watch(() => props.fullscreen, (val) => {
  isFullscreen.value = !!val
  nextTick(() => {
    if (fitAddon && term) {
      try { fitAddon.fit() } catch (_) {}
    }
  })
  // 锁定/恢复页面滚动，避免全屏时页面可滚动
  lockBodyScrollIfNeeded()
})

// 检测 Windows 系统
const isWindows = () => {
  return navigator.platform.toLowerCase().includes('win')
}

// 获取适合 Windows 的字体配置
const getWindowsFontConfig = () => {
  if (isWindows()) {
    return {
      fontFamily: '"Consolas", "Courier New", "Microsoft YaHei Mono", "SimHei", monospace',
      fontSize: 14,
      fontWeight: 'normal',
      fontWeightBold: 'bold',
      lineHeight: 1.2,
      letterSpacing: 0
    }
  }
  return {
    fontFamily: '"Fira Code", "JetBrains Mono", "Consolas", "Courier New", monospace',
    fontSize: 16,
    fontWeight: 'normal',
    fontWeightBold: 'bold',
    lineHeight: 1.4,
    letterSpacing: 0
  }
}

// 获取适合 Windows 的主题配置
const getWindowsTheme = () => {
  if (isWindows()) {
    return {
      foreground: '#D4D4D4',
      background: '#1E1E1E',
      cursor: '#007ACC',
      cursorAccent: '#FFFFFF',
      selection: '#264F78',
      black: '#000000',
      red: '#CD3131',
      green: '#0DBC79',
      yellow: '#E5E510',
      blue: '#2472C8',
      magenta: '#BC3FBC',
      cyan: '#11A8CD',
      white: '#E5E5E5',
      brightBlack: '#666666',
      brightRed: '#F14C4C',
      brightGreen: '#23D18B',
      brightYellow: '#F5F543',
      brightBlue: '#3B8EEA',
      brightMagenta: '#D670D6',
      brightCyan: '#29B8DB',
      brightWhite: '#FFFFFF'
    }
  }
  return {
    foreground: '#D4D4D4',
    background: '#1E1E1E',
    cursor: '#007ACC',
    cursorAccent: '#FFFFFF',
    selection: '#264F78'
  }
}

function init() {
  const fontConfig = getWindowsFontConfig()
  const theme = getWindowsTheme()
  
  // 创建终端实例，针对 Windows 优化
  term = new Terminal({
    ...fontConfig,
    cursorBlink: true,
    cursorStyle: 'block',
    scrollback: 1000,
    theme: theme,
    allowTransparency: false,
    allowProposedApi: true,
    // Windows 特定优化
    windowsMode: isWindows(),
    macOptionIsMeta: !isWindows(),
    rightClickSelectsWord: isWindows(),
    // 改进渲染性能
    fastScrollModifier: 'alt',
    fastScrollSensitivity: 5,
    scrollSensitivity: 1,
    // 改进选择体验
    selectOnLineNumbers: true,
    // 改进复制粘贴 - 启用自动复制到剪贴板
    copyOnSelection: true,
    // 改进字体渲染
    fontLigatures: !isWindows(),
    // 确保终端正常工作
    disableStdin: false
  })

  // 优化数据输入处理
  term.onData((data) => {
    terminalStore.sendInput(data)
    // 延迟滚动到底部，避免频繁重绘
    setTimeout(() => {
      if (term) {
        term.scrollToBottom()
      }
    }, 10)
  })

  // 移除自定义复制处理，使用终端原生的 copyOnSelection 功能

  // 创建并配置 FitAddon
  fitAddon = new FitAddon()
  term.loadAddon(fitAddon)
  term.open(termEl.value)
  
  // 延迟适配，确保容器已渲染
  nextTick(() => {
    fitAddon.fit()
    setupResizeObserver()
  })

  const { host, port = 22, username, password } = props.conn

  // 建立或复用全局 Socket 连接
  terminalStore.connect({ host, port, username, password })

  // 回放历史输出
  if (Array.isArray(terminalStore.history)) {
    terminalStore.history.filter(r => r.type === 'output').forEach(r => term.write(r.content))
  }

  // 订阅实时输出
  unsubscribeOnData = terminalStore.subscribeOnData((data) => {
    term.write(data)
    // 在首次接收到远端输出后，延时一次性发送自动启动命令
    if (!hasAutoStarted) {
      if (autoStartTimer) clearTimeout(autoStartTimer)
      autoStartTimer = setTimeout(() => {
        hasAutoStarted = true
        const cmd = 'cd /root/KylinAIOps106/UI && python cli.py\n'
        terminalStore.sendInput(cmd)
      }, 600)
    }
  })
}

// 设置窗口大小监听
const setupResizeObserver = () => {
  if (resizeObserver) {
    resizeObserver.disconnect()
  }
  
  resizeObserver = new ResizeObserver(() => {
    if (fitAddon && term) {
      try {
        fitAddon.fit()
      } catch (error) {
        console.warn('Terminal fit error:', error)
      }
    }
  })
  
  if (termEl.value) {
    resizeObserver.observe(termEl.value)
  }
}

// 切换全屏
const toggleFullscreen = () => {
  isFullscreen.value = !isFullscreen.value
  nextTick(() => {
    if (fitAddon && term) {
      fitAddon.fit()
    }
  })
}

// 清屏功能
const clearTerminal = () => {
  if (term) {
    term.clear()
    terminalStore.clearHistory()
  }
}

// 窗口大小变化监听
const handleResize = () => {
  if (fitAddon && term) {
    try {
      fitAddon.fit()
    } catch (error) {
      console.warn('Terminal fit error on resize:', error)
    }
  }
}

onMounted(() => {
  window.addEventListener('resize', handleResize)
  window.addEventListener('keydown', onKeydown)
  
  // 只添加右键菜单处理，不干扰其他鼠标事件
  if (termEl.value) {
    termEl.value.addEventListener('contextmenu', handleContextMenu)
  }
  
  // 全屏容器首次渲染后适配
  nextTick(() => {
    if (fitAddon && term) {
      try { fitAddon.fit() } catch (_) {}
    }
  })
  // 初始根据 fullscreen 状态锁定页面滚动
  lockBodyScrollIfNeeded()
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  window.removeEventListener('keydown', onKeydown)
  
  // 移除右键菜单监听器
  if (termEl.value) {
    termEl.value.removeEventListener('contextmenu', handleContextMenu)
  }
  
  if (resizeObserver) {
    resizeObserver.disconnect()
  }
  // 恢复页面滚动
  if (typeof restoreBodyOverflow === 'function') {
    try { restoreBodyOverflow() } catch (_) {}
    restoreBodyOverflow = null
  }
})

onBeforeUnmount(() => {
  close()
  if (resizeObserver) {
    resizeObserver.disconnect()
  }
  if (fitAddon) {
    fitAddon.dispose()
  }
  if (term) {
    term.dispose()
  }
})

// 锁定 body 滚动，避免全屏终端背后页面滚动
function lockBodyScrollIfNeeded() {
  if (visible.value) {
    const previous = document.body.style.overflow
    document.body.style.overflow = 'hidden'
    restoreBodyOverflow = () => { document.body.style.overflow = previous }
  } else {
    if (typeof restoreBodyOverflow === 'function') {
      try { restoreBodyOverflow() } catch (_) {}
      restoreBodyOverflow = null
    }
  }
}

// 处理快捷键（Esc 关闭）
function onKeydown(e) {
  if (!visible.value) return
  
  // 处理 Esc 键关闭终端
  if (e.key === 'Escape') {
    e.preventDefault()
    close()
    return
  }
  
  // 让终端处理所有其他键盘事件，包括 Ctrl+C
  // 终端会自动处理复制和中断信号
}

// 这些函数已移除，让终端使用原生的事件处理机制

// 处理右键菜单事件
function handleContextMenu(e) {
  e.preventDefault()
  // 不显示右键菜单，避免与终端功能冲突
}

// 复制按钮相关函数已移除，使用终端原生复制功能
</script>

<style scoped>
/* 终端对话框样式 */
.terminal-dialog {
  --terminal-bg: #1E1E1E;
  --terminal-fg: #D4D4D4;
  --terminal-border: #3C3C3C;
  --terminal-header-bg: #2D2D30;
  --terminal-header-fg: #CCCCCC;
}

.terminal-dialog :deep(.el-dialog) {
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}

.terminal-dialog :deep(.el-dialog__header) {
  padding: 0;
  background: var(--terminal-header-bg);
  border-bottom: 1px solid var(--terminal-border);
}

.terminal-dialog :deep(.el-dialog__body) {
  padding: 0;
  background: var(--terminal-bg);
}

.terminal-dialog :deep(.el-dialog__footer) {
  padding: 12px 20px;
  background: var(--terminal-header-bg);
  border-top: 1px solid var(--terminal-border);
  text-align: right;
}

.terminal-dialog-fullscreen :deep(.el-dialog) {
  border-radius: 0;
  margin: 0;
  position: fixed;
  inset: 0; /* top/right/bottom/left = 0 */
  width: 100vw;
  max-width: 100vw;
  height: 100vh;
  max-height: 100vh;
  border: 0;
}

.terminal-dialog-fullscreen :deep(.el-dialog__header),
.terminal-dialog-fullscreen :deep(.el-dialog__footer) {
  display: none;
}

.terminal-dialog-fullscreen :deep(.el-dialog__body) {
  height: 100%;
  overflow: hidden;
}

/* 终端头部样式 */
.terminal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 20px;
  background: var(--terminal-header-bg);
  color: var(--terminal-header-fg);
  border-bottom: 1px solid var(--terminal-border);
}

.terminal-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--terminal-header-fg);
}

.terminal-controls {
  display: flex;
  gap: 8px;
  align-items: center;
}

.terminal-controls .el-button {
  color: var(--terminal-header-fg);
  border: none;
  background: transparent;
  padding: 6px 12px;
  border-radius: 4px;
  transition: all 0.2s ease;
}

.terminal-controls .el-button:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #FFFFFF;
}

/* 终端容器样式 */
.terminal-container {
  position: relative;
  width: 100%;
  height: 70vh;
  min-height: 400px;
  background: var(--terminal-bg);
  overflow: hidden;
}

.terminal-dialog-fullscreen .terminal-container {
  height: 100%;
  min-height: 100%;
}

.terminal-content {
  width: 100%;
  height: 100%;
  padding: 8px;
  box-sizing: border-box;
  background: var(--terminal-bg);
  overflow: hidden;
}

.terminal-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  width: 100%;
}

.terminal-footer-actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

.terminal-footer-actions .el-button {
  min-width: 80px;
}

/* Windows 特定优化 */
@media screen and (-webkit-min-device-pixel-ratio: 0) {
  .terminal-content {
    /* 改善 Windows 上的字体渲染 */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .terminal-container {
    height: 60vh;
    min-height: 300px;
  }
  
  .terminal-header {
    padding: 8px 16px;
  }
  
  .terminal-title {
    font-size: 14px;
  }
  
  .terminal-controls .el-button {
    padding: 4px 8px;
    font-size: 12px;
  }
}

@media (max-width: 480px) {
  .terminal-container {
    height: 50vh;
    min-height: 250px;
  }
  
  .terminal-controls {
    gap: 4px;
  }
  
  .terminal-controls .el-button {
    padding: 3px 6px;
    font-size: 11px;
  }
}

/* 终端内容样式覆盖 */
.terminal-content :deep(.xterm) {
  height: 100% !important;
  width: 100% !important;
}

.terminal-content :deep(.xterm-viewport) {
  background: var(--terminal-bg) !important;
  scrollbar-width: thin;
  scrollbar-color: #555 #333;
}

.terminal-content :deep(.xterm-viewport::-webkit-scrollbar) {
  width: 8px;
}

.terminal-content :deep(.xterm-viewport::-webkit-scrollbar-track) {
  background: #333;
}

.terminal-content :deep(.xterm-viewport::-webkit-scrollbar-thumb) {
  background: #555;
  border-radius: 4px;
}

.terminal-content :deep(.xterm-viewport::-webkit-scrollbar-thumb:hover) {
  background: #777;
}

/* 改善 Windows 上的选择体验 */
.terminal-content :deep(.xterm .xterm-selection div) {
  background: rgba(38, 79, 120, 0.3) !important;
}

/* 改善终端选择和复制体验 */
.terminal-content :deep(.xterm .xterm-selection) {
  background: rgba(38, 79, 120, 0.4) !important;
}

.terminal-content :deep(.xterm .xterm-selection .xterm-selection-layer) {
  background: rgba(38, 79, 120, 0.4) !important;
}

/* 鼠标悬停效果 */
.terminal-content :deep(.xterm) {
  cursor: text;
}

.terminal-content :deep(.xterm .xterm-screen) {
  user-select: text;
  -webkit-user-select: text;
  -moz-user-select: text;
  -ms-user-select: text;
}

/* 改善光标显示 */
.terminal-content :deep(.xterm .xterm-cursor-layer .xterm-cursor) {
  background: #007ACC !important;
  color: #FFFFFF !important;
}

/* 全屏模式优化 */
.terminal-dialog-fullscreen .terminal-content {
  padding: 0;
}

/* 新的全屏容器样式（脱离 el-dialog） */
.terminal-fullscreen {
  position: fixed;
  inset: 0;
  background: var(--terminal-bg, #1E1E1E);
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
  z-index: 9999;
}

/* 顶部工具栏已移除 */

.terminal-fullscreen-container {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

.terminal-controls-floating {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 10000;
}

.terminal-btn {
  appearance: none;
  border: 1px solid #409eff;
  background: #409eff;
  color: #fff;
  border-radius: 6px;
  padding: 6px 12px;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
  font-size: 14px;
  min-width: 60px;
}

.terminal-btn:hover {
  background: #66b1ff;
  border-color: #66b1ff;
}

.terminal-btn:active {
  background: #3a8ee6;
  border-color: #3a8ee6;
}

.terminal-content.fullscreen {
  width: 100%;
  height: 100%;
  padding: 0;
}

/* 暗色主题适配 */
@media (prefers-color-scheme: dark) {
  .terminal-dialog {
    --terminal-bg: #0D1117;
    --terminal-fg: #C9D1D9;
    --terminal-border: #30363D;
    --terminal-header-bg: #161B22;
    --terminal-header-fg: #F0F6FC;
  }
}

/* 高对比度模式支持 */
@media (prefers-contrast: high) {
  .terminal-dialog {
    --terminal-bg: #000000;
    --terminal-fg: #FFFFFF;
    --terminal-border: #FFFFFF;
    --terminal-header-bg: #000000;
    --terminal-header-fg: #FFFFFF;
  }
  
  .terminal-content :deep(.xterm .xterm-cursor-layer .xterm-cursor) {
    background: #FFFFFF !important;
    color: #000000 !important;
  }
}
</style>